package com.h117121.fashionshop.controller.admin;

import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import com.h117121.fashionshop.constant.AppConstant;
import com.h117121.fashionshop.controller.generic.GenericController;
import com.h117121.fashionshop.core.dom.Account;
import com.h117121.fashionshop.core.dom.Account.AccountStatus;
import com.h117121.fashionshop.core.dom.Account.Sex;
import com.h117121.fashionshop.core.dom.Account.UserType;
import com.h117121.fashionshop.core.dom.SimpleQuery;
import com.h117121.fashionshop.core.exception.EntityNotFoundException;
import com.h117121.fashionshop.validator.AdminUpdateAccountValidator;

@Controller
@RequestMapping("/admin/account")
public class AdminAccountController extends GenericController {
	@Autowired
	private MessageSource messageSource;

	@Autowired
	private AdminUpdateAccountValidator validator;

	@RequestMapping(method = RequestMethod.GET)
	protected String showPage(HttpServletRequest request,
			@ModelAttribute(value = "query") SimpleQuery query,
			@RequestParam(value = "page", required = false) String page) {
		int indexPage = 0;
		if (page != null && !page.isEmpty()) {
			try {
				indexPage = Integer.parseInt(page);
				indexPage -= 1;
				if (indexPage < 0)
					indexPage = 0;
			} catch (NumberFormatException e) {
				indexPage = 0;
			}
		}

		if (query.getKeyWord() != null && !query.getKeyWord().isEmpty()) {
			request.setAttribute("resultPage", businessService.findAccount(
					query.getKeyWord(), indexPage,
					AppConstant.ADMIN_NUM_ITEM_PER_PAGE));
			String paraURL = ((HttpServletRequest) request).getQueryString();
			if (paraURL.contains("&page=")) {
				request.setAttribute("pageURL",
						paraURL.substring(0, paraURL.indexOf("&page=")));
			} else {
				request.setAttribute("pageURL", paraURL);
			}
		} else {
			request.setAttribute("resultPage", businessService.getAllAccount(
					indexPage, AppConstant.ADMIN_NUM_ITEM_PER_PAGE));
		}

		return "AdminAccountPage";
	}

	@RequestMapping(value = "/delete", method = RequestMethod.GET)
	protected String deleteProduct(HttpServletRequest request,
			@RequestParam(value = "pid", required = true) String id)
			throws ServletException, IOException {
		String referer = request.getHeader("Referer");
		String queryString = "";
		if (referer != null) {
			if (referer.contains("?")) {
				queryString = referer.substring(referer.indexOf("?"));
			}
		}

		Account acc = (Account) request.getSession().getAttribute("account");
		if (acc != null) {
			if (Long.parseLong(id) == acc.getId()) {
				request.setAttribute("deleteYourself", true);
				return "forward:/admin/account" + queryString;
			}
		}

		try {
			businessService.deleteAccount(businessService.getAccount(Long
					.parseLong(id)));
			request.setAttribute("successfulMessage", true);
		} catch (EntityNotFoundException e) {
			request.setAttribute("notfound", true);
		}

		return "forward:/admin/account" + queryString;
	}

	@ModelAttribute("sexs")
	public Map<Sex, String> populateSex() {
		Map<Sex, String> sexs = new LinkedHashMap<Sex, String>();
		for (Sex item : Sex.values()) {
			sexs.put(item, item.name());
		}
		return sexs;
	}

	@ModelAttribute("accountTypes")
	public Map<UserType, String> populateaccountTypes() {
		Map<UserType, String> accountTypes = new LinkedHashMap<UserType, String>();
		for (UserType item : UserType.values()) {
			accountTypes.put(item, item.name());
		}
		return accountTypes;
	}

	@ModelAttribute("accountStatuses")
	public Map<AccountStatus, String> populateaccountStatuses() {
		Map<AccountStatus, String> accountStatuses = new LinkedHashMap<AccountStatus, String>();
		for (AccountStatus item : AccountStatus.values()) {
			accountStatuses.put(item, item.name());
		}
		return accountStatuses;
	}

	@RequestMapping(value = "/edit", method = RequestMethod.GET)
	protected String showEditAccount(
			@RequestParam(value = "pid", required = false) String id,
			ModelMap model, @ModelAttribute(value = "account") Account account,
			BindingResult errors) {
		if (id != null) {
			try {
				model.addAttribute("account",
						businessService.getAccount(Long.parseLong(id)));
			} catch (EntityNotFoundException e) {
				errors.reject("notfound.account");
			}
		} else {
			model.addAttribute("account", new Account());
		}
		return "AdminAccountDetailPage";
	}

	@RequestMapping(value = "/edit", method = RequestMethod.POST)
	protected String editAccount(HttpServletRequest request,
			@RequestParam(value = "pid", required = false) String id,
			@ModelAttribute(value = "account") Account account,
			BindingResult errors, ModelMap model) {
		validator.validate(account, errors);
		if (errors.hasErrors()) {
			return "AdminAccountDetailPage";
		}

		try {
			businessService.updateAccountAdmin(account);
		} catch (EntityNotFoundException e) {
			errors.reject("notfound.account");
		}
		model.addAttribute("successfulMessage", true);
		return "AdminAccountDetailPage";
	}
}
